home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Macintosh Tracker 1.20 / source / Tracker Client Folder / CSongList.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-23  |  13.5 KB  |  508 lines  |  [TEXT/KAHL]

  1. /* CSongList.c */
  2.  
  3. #include "CSongList.h"
  4. #include "CVScrollBar.h"
  5. #include "CMyDocument.h"
  6. #include "CWindow.h"
  7. #include "CArray.h"
  8. #include "CApplication.h"
  9. #include "Memory.h"
  10. #include "MenuController.h"
  11. #include "LocationConstants.h"
  12. #include "CMyApplication.h"
  13.  
  14.  
  15. #define InitialOffset (1)
  16. #define MarkerInset (5)
  17. #define SELECTIONTHICKNESS (2)
  18. #define MaxTypedCharDelay (30)
  19.  
  20.  
  21. void                CSongList::ISongList(CMyDocument* TheDocument, CWindow* TheWindow)
  22.     {
  23.         LongPoint            Start,Extent;
  24.         CVScrollBar*    OurScroller;
  25.         FontInfo            MyFontInfo;
  26.  
  27.         Document = TheDocument;
  28.         GetRect(ScrollingListLocID,&Start,&Extent);
  29.         IViewRect(Start,Extent,TheWindow,TheWindow);
  30.  
  31.         GetRect(ScrollingListBarLocID,&Start,&Extent);
  32.         OurScroller = new CVScrollBar;
  33.         VScroll = OurScroller;
  34.         OurScroller->IVScrollBar(Start,Extent,this,TheWindow,TheWindow);
  35.  
  36.         LastClickTime = TickCount();
  37.         LastCharTime = TickCount();
  38.         StartingIndex = 0;
  39.         CharBufferLength = 0;
  40.  
  41.         SetUpPort();
  42.         Window->SetText(systemFont,0,srcCopy,12,0);
  43.         GetFontInfo(&MyFontInfo);
  44.         LineHeight = MyFontInfo.leading + MyFontInfo.ascent + MyFontInfo.descent;
  45.     }
  46.  
  47.  
  48. void                CSongList::DoMouseDown(MyEventRec Event)
  49.     {
  50.         long                SongIndex;
  51.         long                CurrentIndex;
  52.  
  53.         BecomeKeyReceiver();
  54.         Event.Where = MyGlobalToLocal(Event.Where);
  55.         SongIndex = StartingIndex + (Event.Where.y / LineHeight);
  56.  
  57.         if (((Event.Modifiers & optionKey) != 0) && (Document->Selection != -1))
  58.             {
  59.                 MyBoolean            InWindow;
  60.  
  61.              MoveSelection:
  62.                 CurrentIndex = -1;
  63.                 InWindow = False;
  64.                 do
  65.                     {
  66.                         long                    Index2;
  67.  
  68.                         Event.Where = MyGlobalToLocal(GetLongMouseLoc());
  69.                         if ((Event.Where.y < 0) && (StartingIndex > 0))
  70.                             {
  71.                                 Hook(VScrollUpOne,0,0);
  72.                             }
  73.                         if ((Event.Where.y > Extent.y) && (StartingIndex <
  74.                             Document->ListOfSongs->GetNumElements() - ((Extent.y - 2) / LineHeight)))
  75.                             {
  76.                                 Hook(VScrollDownOne,0,0);
  77.                             }
  78.                         Index2 = StartingIndex + (Event.Where.y / LineHeight);
  79.                         if ((Event.Where.x >= 0) && (Event.Where.x < Extent.x))
  80.                             {
  81.                                 if ((CurrentIndex != Index2) || !InWindow)
  82.                                     {
  83.                                         InWindow = True;
  84.                                         Redraw(CurrentIndex - 1,CurrentIndex);
  85.                                         CurrentIndex = Index2;
  86.                                         SetUpPort();
  87.                                         Window->ResetPen();
  88.                                         Window->LEraseRect(LongPointOf(1,(CurrentIndex - StartingIndex)
  89.                                             * LineHeight - SELECTIONTHICKNESS - 1),LongPointOf(Extent.x - 2,1));
  90.                                         Window->LPaintRect(LongPointOf(1,(CurrentIndex - StartingIndex)
  91.                                             * LineHeight - SELECTIONTHICKNESS),
  92.                                             LongPointOf(Extent.x - 2,2 * SELECTIONTHICKNESS));
  93.                                         Window->LEraseRect(LongPointOf(1,(CurrentIndex - StartingIndex)
  94.                                             * LineHeight + SELECTIONTHICKNESS),LongPointOf(Extent.x - 2,1));
  95.                                     }
  96.                             }
  97.                          else
  98.                             {
  99.                                 if ((CurrentIndex != Index2) || InWindow)
  100.                                     {
  101.                                         InWindow = False;
  102.                                         Redraw(CurrentIndex - 1,CurrentIndex);
  103.                                         CurrentIndex = Index2;
  104.                                     }
  105.                             }
  106.                         RelinquishCPUJudiciously();
  107.                     } while (StillDown());
  108.                 Redraw(CurrentIndex - 1,CurrentIndex);
  109.                 if (InWindow)
  110.                     {
  111.                         /* only move item if mouse released inside the pane */
  112.                         Document->MoveSong(Document->Selection,CurrentIndex);
  113.                     }
  114.                 return;
  115.             }
  116.  
  117.         if ((Event.When - LastClickTime < DoubleTime)
  118.             && (SongIndex == Document->Selection))
  119.             {
  120.                 /* double click--stop current song and play new song */
  121.                 Document->StartThisSong(SongIndex);
  122.             }
  123.          else
  124.             {
  125.                 /* single click--just change the selection */
  126.                 if ((SongIndex >= 0) && (SongIndex < Document->ListOfSongs->GetNumElements()))
  127.                     {
  128.                         Document->SetNewSelection(SongIndex);
  129.                     }
  130.                 while (StillDown())
  131.                     {
  132.                         Event.Where = MyGlobalToLocal(GetLongMouseLoc());
  133.                         CurrentIndex = StartingIndex + (Event.Where.y / LineHeight);
  134.                         if (CurrentIndex != SongIndex)
  135.                             {
  136.                                 goto MoveSelection;
  137.                             }
  138.                         RelinquishCPUJudiciously();
  139.                     }
  140.             }
  141.         LastClickTime = Event.When;
  142.     }
  143.  
  144.  
  145. MyBoolean        CSongList::DoKeyDown(MyEventRec Event)
  146.     {
  147.         long                Temp;
  148.  
  149.         switch (Event.Message & charCodeMask)
  150.             {
  151.                 case (uchar)0x1e:  /* macintosh up arrow */
  152.                     if (Document->Selection > 0)
  153.                         {
  154.                             long            StartTemp;
  155.  
  156.                             Document->SetNewSelection(Document->Selection - 1);
  157.                          GetSelectionOnScreen:
  158.                             StartTemp = StartingIndex;
  159.                             while (Document->Selection < StartTemp)
  160.                                 {
  161.                                     StartTemp -= 1;
  162.                                 }
  163.                             while (Document->Selection > StartTemp
  164.                                 + ((Extent.y - 2) / LineHeight) - 1)
  165.                                 {
  166.                                     StartTemp += 1;
  167.                                 }
  168.                             Hook(VScrollToLocation,StartTemp,0);
  169.                         }
  170.                     return True;
  171.                 case (uchar)0x1f:  /* macintosh down arrow */
  172.                     if (Document->Selection < Document->ListOfSongs->GetNumElements() - 1)
  173.                         {
  174.                             Document->SetNewSelection(Document->Selection + 1);
  175.                             goto GetSelectionOnScreen;
  176.                         }
  177.                     return True;
  178.                 case (uchar)0x0d:  /* return key */
  179.                 case (uchar)0x03:  /* enter key */
  180.                     Document->StartThisSong(Document->Selection);
  181.                     return True;
  182.                 default:
  183.                     BecomeKeyReceiver();
  184.                     if (TickCount() - LastCharTime > MaxTypedCharDelay)
  185.                         {
  186.                             CharBufferLength = 0;
  187.                         }
  188.                     if (CharBufferLength < MAXTYPEDCHARS)
  189.                         {
  190.                             CharBuffer[CharBufferLength] = Event.Message & charCodeMask;
  191.                             CharBufferLength += 1;
  192.                         }
  193.                     Temp = 0;
  194.                     while (Temp < Document->ListOfSongs->GetNumElements())
  195.                         {
  196.                             SongRec*            TempSongLoc;
  197.  
  198.                             TempSongLoc = Document->ListOfSongs->GetElementAddress(Temp);
  199.                             /* we won't move memory... I promise! */
  200.                             if (TempSongLoc->SongName[0] >= CharBufferLength)
  201.                                 {
  202.                                     MyBoolean                OK;
  203.                                     short                        Scan;
  204.                                     char                        First;
  205.                                     char                        Second;
  206.  
  207.                                     OK = True;
  208.                                     Scan = 0;
  209.                                     while ((Scan < CharBufferLength) && OK)
  210.                                         {
  211.                                             First = CharBuffer[Scan];
  212.                                             Second = TempSongLoc->SongName[Scan + 1];
  213.                                             if ((First >= 'A') && (First <= 'Z'))
  214.                                                 {
  215.                                                     First = First - 'A' + 'a';
  216.                                                 }
  217.                                             if ((Second >= 'A') && (Second <= 'Z'))
  218.                                                 {
  219.                                                     Second = Second - 'A' + 'a';
  220.                                                 }
  221.                                             OK = (First == Second);
  222.                                             Scan += 1;
  223.                                         }
  224.                                     if (OK)
  225.                                         {
  226.                                             Document->SetNewSelection(Temp);
  227.                                             LastCharTime = TickCount();
  228.                                             goto GetSelectionOnScreen;
  229.                                         }
  230.                                 }
  231.                             Temp += 1;
  232.                         }
  233.                     Document->SetNewSelection(-1);
  234.                     LastCharTime = TickCount();
  235.                     return True;
  236.             }
  237.     }
  238.  
  239.  
  240. void                CSongList::DoUpdate(void)
  241.     {
  242.         SetUpPort();
  243.         Window->ResetPen();
  244.         Window->LFrameRect(ZeroPoint,Extent);
  245.         Redraw(StartingIndex,StartingIndex + ((Extent.y - 2) / LineHeight + 1));
  246.     }
  247.  
  248.  
  249. MyBoolean        CSongList::DoMenuCommand(ushort MenuCommandValue)
  250.     {
  251.         long                Temp;
  252.         long                StartTemp;
  253.  
  254.         switch (MenuCommandValue)
  255.             {
  256.                 case mFileClose:
  257.                     Document->GoAway();
  258.                     return True;
  259.                 case mFileSaveAs:
  260.                     Document->SaveFileAs();
  261.                     return True;
  262.                 case mFileSave:
  263.                     Document->SaveFile();
  264.                     return True;
  265.                 case mDeleteSelection:
  266.                     Document->RemoveSongFromList(Document->Selection);
  267.                     Temp = Document->Selection;
  268.                     Document->SetNewSelection(-1);
  269.                     return True;
  270.                 case mPlaySelection:
  271.                     Document->StartThisSong(Document->Selection);
  272.                     return True;
  273.                 case mStopPlaying:
  274.                     Document->CancelCurrentSong();
  275.                     return True;
  276.                 case mIncreaseVolume:
  277.                     Document->DoVolumeUp();
  278.                     return True;
  279.                 case mDecreaseVolume:
  280.                     Document->DoVolumeDown();
  281.                     return True;
  282.                 case mShowSelection:
  283.                     StartTemp = StartingIndex;
  284.                     while (Document->Selection < StartTemp)
  285.                         {
  286.                             StartTemp -= 1;
  287.                         }
  288.                     while (Document->Selection > StartTemp + ((Extent.y - 2) / LineHeight) - 1)
  289.                         {
  290.                             StartTemp += 1;
  291.                         }
  292.                     Hook(VScrollToLocation,StartTemp,0);
  293.                     return True;
  294.                 case mShowPlaying:
  295.                     StartTemp = StartingIndex;
  296.                     while (Document->Playing < StartTemp)
  297.                         {
  298.                             StartTemp -= 1;
  299.                         }
  300.                     while (Document->Playing > StartTemp + ((Extent.y - 2) / LineHeight) - 1)
  301.                         {
  302.                             StartTemp += 1;
  303.                         }
  304.                     Hook(VScrollToLocation,StartTemp,0);
  305.                     return True;
  306.                 case mUseEspieTracker:
  307.                     Document->SetTrackerServerToUse(eTrackerMarkEspie);
  308.                     break;
  309.                 case mUseSeideTracker:
  310.                     Document->SetTrackerServerToUse(eTrackerFrankSeide);
  311.                     break;
  312.                 case mUseRossetTracker:
  313.                     Document->SetTrackerServerToUse(eTrackerAntoineRosset);
  314.                     break;
  315.                 default:
  316.                     return Application->DoMenuCommand(MenuCommandValue);
  317.             }
  318.     }
  319.  
  320.  
  321. void                CSongList::EnableMenuItems(void)
  322.     {
  323.         Application->EnableMenuItems();
  324.         MyEnableItem(mFileClose);
  325.         MyEnableItem(mFileSaveAs);
  326.         if (!Document->UpToDate)
  327.             {
  328.                 MyEnableItem(mFileSave);
  329.             }
  330.         if (Document->Playing != -1)
  331.             {
  332.                 MyEnableItem(mStopPlaying);
  333.                 MyEnableItem(mIncreaseVolume);
  334.                 MyEnableItem(mDecreaseVolume);
  335.             }
  336.         if (Document->Selection != -1)
  337.             {
  338.                 MyEnableItem(mDeleteSelection);
  339.                 MyEnableItem(mPlaySelection);
  340.             }
  341.         if (Document->Selection != -1)
  342.             {
  343.                 MyEnableItem(mShowSelection);
  344.             }
  345.         if (Document->Playing != -1)
  346.             {
  347.                 MyEnableItem(mShowPlaying);
  348.             }
  349.         if (Document->Selection != -1)
  350.             {
  351.                 MyEnableItem(mUseEspieTracker);
  352.                 MySetItemMark(mUseEspieTracker,noMark);
  353.                 MyEnableItem(mUseSeideTracker);
  354.                 MySetItemMark(mUseSeideTracker,noMark);
  355.                 MyEnableItem(mUseRossetTracker);
  356.                 MySetItemMark(mUseRossetTracker,noMark);
  357.                 switch (Document->FindOutTrackerServerToUse())
  358.                     {
  359.                         case eTrackerMarkEspie:
  360.                             MySetItemMark(mUseEspieTracker,checkMark);
  361.                             break;
  362.                         case eTrackerFrankSeide:
  363.                             MySetItemMark(mUseSeideTracker,checkMark);
  364.                             break;
  365.                         case eTrackerAntoineRosset:
  366.                             MySetItemMark(mUseRossetTracker,checkMark);
  367.                             break;
  368.                     }
  369.             }
  370.     }
  371.  
  372.  
  373. void                CSongList::Redraw(long Start, long End)
  374.     {
  375.         long                Scan;
  376.         LongPoint        TopLeft;
  377.         LongPoint        BottomRight;
  378.         Handle            String;
  379.         SongRec            Temp;
  380.  
  381.         SetUpPort();
  382.         Window->SetClipRect(LongPointOf(1,1),LongPointOf(Extent.x - 2,Extent.y - 2));
  383.         Window->SetText(systemFont,0,srcCopy,12,0);
  384.         for (Scan = Start; Scan <= End; Scan += 1)
  385.             {
  386.                 TopLeft.x = 1;
  387.                 TopLeft.y = (Scan - StartingIndex) * LineHeight + 1;
  388.                 BottomRight.x = Extent.x - 2;
  389.                 BottomRight.y = LineHeight;
  390.                 if (Scan != Document->Selection)
  391.                     {
  392.                         Window->LEraseRect(TopLeft,BottomRight);
  393.                         Window->SetTextMode(srcCopy);
  394.                         Window->SetPenMode(patCopy);
  395.                     }
  396.                  else
  397.                     {
  398.                         Window->LPaintRect(TopLeft,BottomRight);
  399.                         Window->SetTextMode(srcBic);
  400.                         Window->SetPenMode(patBic);
  401.                     }
  402.                 TopLeft.x += 5;
  403.                 BottomRight.x -= 5;
  404.                 if (Scan == Document->Playing)
  405.                     {
  406.                         Window->LPaintOval(LongPointOf(TopLeft.x,TopLeft.y + MarkerInset
  407.                             + InitialOffset),LongPointOf(LineHeight - MarkerInset * 2,
  408.                             LineHeight - MarkerInset * 2));
  409.                     }
  410.                 TopLeft.x += LineHeight - MarkerInset * 2 + 8;
  411.                 BottomRight.x -= LineHeight - MarkerInset * 2 + 8;
  412.                 if (Document->ListOfSongs->GetElement(Scan,&Temp))
  413.                     {
  414.                         String = PString2Handle(Temp.SongName);
  415.                         Window->LDrawText(TopLeft,BottomRight,String,JustifyLeft);
  416.                         ReleaseHandle(String);
  417.                     }
  418.             }
  419.     }
  420.  
  421.  
  422. void                CSongList::RecalculateScrollBars(void)
  423.     {
  424.         VScroll->SetPosition(StartingIndex,Document->ListOfSongs->GetNumElements()
  425.             - ((Extent.y - 2) / LineHeight) + 1);
  426.     }
  427.  
  428.  
  429. long                CSongList::Hook(short OperationID, long Operand1, long Operand2)
  430.     {
  431.         SetUpPort();
  432.         Window->SetClipRect(LongPointOf(1,1),LongPointOf(Extent.x - 2,Extent.y - 2));
  433.         switch (OperationID)
  434.             {
  435.                 case VScrollToLocation:
  436.                     {
  437.                         long                Delta;
  438.  
  439.                         if (Operand1 < 0)
  440.                             {
  441.                                 Operand1 = 0;
  442.                             }
  443.                         if ((Operand1 > Document->ListOfSongs->GetNumElements()
  444.                             - ((Extent.y - 2) / LineHeight)) && (Document->ListOfSongs->GetNumElements()
  445.                             - ((Extent.y - 2) / LineHeight) > 0))
  446.                             {
  447.                                 Operand1 = Document->ListOfSongs->GetNumElements()
  448.                                     - ((Extent.y - 2) / LineHeight);
  449.                             }
  450.                         Delta = Operand1 - StartingIndex; /* how many cells to move down by */
  451.                         Window->ScrollLong(LongPointOf(1,1),LongPointOf(Extent.x - 2,Extent.y - 2),
  452.                             LongPointOf(0,(-Delta) * LineHeight));
  453.                         StartingIndex += Delta;
  454.                         if (Delta < 0)
  455.                             {
  456.                                 /* shifted image down; opened at top */
  457.                                 Redraw(StartingIndex,StartingIndex - Delta);
  458.                             }
  459.                          else
  460.                             {
  461.                                 /* shifted up, opened at bottom */
  462.                                 Redraw(StartingIndex + ((Extent.y - 2) / LineHeight) - Delta,
  463.                                     StartingIndex + ((Extent.y - 2) / LineHeight) + 1);
  464.                             }
  465.                         VScroll->SetPosition(StartingIndex,Document->ListOfSongs->GetNumElements()
  466.                             - ((Extent.y - 2) / LineHeight) + 1);
  467.                     }
  468.                     return 0;
  469.                 case VScrollUpOne:
  470.                     if (StartingIndex - 1 >= 0)
  471.                         {
  472.                             return Hook(VScrollToLocation,StartingIndex - 1,0);
  473.                         }
  474.                     return 0;
  475.                 case VScrollUpPage:
  476.                     if (StartingIndex - ((Extent.y - 2) / LineHeight - 1) < 0)
  477.                         {
  478.                             return Hook(VScrollToLocation,0,0);
  479.                         }
  480.                      else
  481.                         {
  482.                             return Hook(VScrollToLocation,StartingIndex
  483.                                 - (Extent.y / LineHeight - 1),0);
  484.                         }
  485.                 case VScrollDownOne:
  486.                     if (StartingIndex + 1 <= Document->ListOfSongs->GetNumElements()
  487.                         - ((Extent.y - 2) / LineHeight))
  488.                         {
  489.                             return Hook(VScrollToLocation,StartingIndex + 1,0);
  490.                         }
  491.                     return 0;
  492.                 case VScrollDownPage:
  493.                     if (StartingIndex + ((Extent.y - 2) / LineHeight - 1)
  494.                         > Document->ListOfSongs->GetNumElements() - ((Extent.y - 2) / LineHeight))
  495.                         {
  496.                             return Hook(VScrollToLocation,Document->ListOfSongs->GetNumElements()
  497.                                 - ((Extent.y - 2) / LineHeight),0);
  498.                         }
  499.                      else
  500.                         {
  501.                             return Hook(VScrollToLocation,StartingIndex
  502.                                 + ((Extent.y - 2) / LineHeight - 1),0);
  503.                         }
  504.                 default:
  505.                     return inherited::Hook(OperationID,Operand1,Operand2);
  506.             }
  507.     }
  508.